# -*- coding: utf-8 -*-
# @author: HRUN

from django.core.cache import cache
import json
import yaml
import os
import tempfile

from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet
from rest_framework.parsers import MultiPartParser, FormParser, JSONParser

from public.models import WxPush
from public.serializers import WxPushSerializer
from projects.models import Project
from projects.serializers import newInterfaceSerializer

from common.pagination import TenPerPageNumberPagination
from .tasks import import_run_yapi
from common.ProjectBoard import ProjectBoard

def truncate_name(prefix, suffix, max_length=50):
    """
    截断名称，确保不超过指定长度
    """
    # 计算前缀长度
    prefix_len = len(prefix)
    # 计算可用长度（减去前缀和连字符）
    available_len = max_length - prefix_len - 1  # -1 for the hyphen
    
    if available_len <= 0:
        # 如果前缀太长，直接返回前缀
        return prefix[:max_length]
    
    # 如果后缀长度在可用范围内，直接拼接
    if len(suffix) <= available_len:
        return f"{prefix}-{suffix}"
    
    # 如果后缀太长，截断后缀
    truncated_suffix = suffix[:available_len]
    return f"{prefix}-{truncated_suffix}"

class WxPushViewSet(ModelViewSet):
    """项目视图集"""
    queryset = WxPush.objects.all().order_by('-create_time')
    serializer_class = WxPushSerializer
    pagination_class = TenPerPageNumberPagination
    filterset_fields = ['project_id']

    def get_queryset(self):
        queryset = super().get_queryset()
        # 获取参数
        project = self.request.query_params.get('project')
        # 过滤
        if project:
            queryset = queryset.filter(project_id=project)

        return queryset


class YApiViewSet(APIView):
    """
    YApi数据导入
    """
    def post(self, request, *args):
        try:
            import_run_yapi(request.data)
            return Response(status=status.HTTP_201_CREATED)
        except Exception as e:
            return Response({"message": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class CurlViewSet(APIView):
    """
    Curl命令导入
    """
    def post(self, request, *args):
        try:
            # 获取请求数据
            data = request.data
            method = data.get('method', 'GET')
            url = data.get('url', '')
            headers = data.get('headers', {})
            body = data.get('body', {})
            project = data.get('project', None)
            treenode = data.get('treenode', None)
            
            # 清理URL，移除多余的字符
            url = url.strip().strip('"').strip("'").replace('^', '').lstrip('"').rstrip('"')
            
            # 构建接口数据
            url_suffix = url.split('/')[-1] or url
            interface_data = {
                "name": truncate_name("CURL导入", url_suffix),
                "url": url,
                "method": method,
                "treenode": treenode,
                "project": project,
                "creator": self.request.user.username,
                "headers": headers,
                "request": {"json": body, "data": None, "params": {}}
            }
            
            # 创建接口
            from projects.serializers import newInterfaceSerializer
            serializer = newInterfaceSerializer(data=interface_data)
            if serializer.is_valid():
                serializer.save()
                return Response(status=status.HTTP_201_CREATED)
            else:
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            return Response({"message": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class PostmanViewSet(APIView):
    """
    Postman集合导入
    """
    parser_classes = (MultiPartParser, FormParser)
    
    def post(self, request, *args):
        try:
            # 获取请求数据
            file_obj = request.FILES.get('file')
            project = request.data.get('project')
            treenode = request.data.get('treenode')
            
            if not file_obj:
                return Response({"message": "未找到文件"}, status=status.HTTP_400_BAD_REQUEST)
            
            # 解析Postman集合文件
            try:
                postman_data = json.loads(file_obj.read().decode('utf-8'))
            except json.JSONDecodeError:
                return Response({"message": "无效的JSON文件"}, status=status.HTTP_400_BAD_REQUEST)
            
            # 处理Postman集合
            if 'item' in postman_data:  # 这是一个集合
                items = postman_data.get('item', [])
                self._process_postman_items(items, project, treenode)
            elif 'values' in postman_data:  # 这是一个环境或全局变量文件
                # 处理环境变量逻辑可以在这里添加
                pass
            else:
                return Response({"message": "不支持的Postman文件格式"}, status=status.HTTP_400_BAD_REQUEST)
            
            return Response(status=status.HTTP_201_CREATED)
        except Exception as e:
            return Response({"message": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    def _process_postman_items(self, items, project, treenode, parent_name=""):
        """递归处理Postman集合中的项目"""
        for item in items:
            if 'item' in item:  # 这是一个文件夹
                folder_name = item.get('name', '')
                # 可以在这里创建子节点
                self._process_postman_items(item['item'], project, treenode, folder_name)
            else:  # 这是一个请求
                self._create_interface_from_postman_request(item, project, treenode, parent_name)
    
    def _create_interface_from_postman_request(self, request_item, project, treenode, parent_name=""):
        """从Postman请求创建接口"""
        name = request_item.get('name', '')
        if parent_name:
            name = f"{parent_name} - {name}"
        
        request_data = request_item.get('request', {})
        url = ""
        if isinstance(request_data.get('url'), dict):
            url = request_data.get('url', {}).get('raw', '')
        elif isinstance(request_data.get('url'), str):
            url = request_data.get('url', '')
        
        method = request_data.get('method', 'GET')
        
        # 处理请求头
        headers = {}
        for header in request_data.get('header', []):
            headers[header.get('key', '')] = header.get('value', '')
        
        # 处理请求体
        body = {}
        if 'body' in request_data:
            body_data = request_data['body']
            if body_data.get('mode') == 'raw' and 'raw' in body_data:
                try:
                    body = json.loads(body_data['raw'])
                except:
                    body = body_data['raw']
            elif body_data.get('mode') == 'formdata':
                form_data = {}
                for item in body_data.get('formdata', []):
                    form_data[item.get('key', '')] = item.get('value', '')
                body = form_data
        
        # 构建接口数据
        interface_data = {
            "name": truncate_name("Postman导入", name),
            "url": url,
            "method": method,
            "treenode": treenode,
            "project": project,
            "creator": self.request.user.username,
            "headers": headers,
            "request": {"json": body, "data": None, "params": {}}
        }
        
        # 创建接口
        serializer = newInterfaceSerializer(data=interface_data)
        if serializer.is_valid():
            serializer.save()
        else:
            print(f"导入失败: {serializer.errors}")


class ApipostViewSet(APIView):
    """
    Apipost集合导入
    """
    parser_classes = (MultiPartParser, FormParser)
    
    def post(self, request, *args):
        try:
            # 获取请求数据
            file_obj = request.FILES.get('file')
            project = request.data.get('project')
            treenode = request.data.get('treenode')
            
            if not file_obj:
                return Response({"message": "未找到文件"}, status=status.HTTP_400_BAD_REQUEST)
            
            # 解析Apipost集合文件
            try:
                apipost_data = json.loads(file_obj.read().decode('utf-8'))
            except json.JSONDecodeError:
                return Response({"message": "无效的JSON文件"}, status=status.HTTP_400_BAD_REQUEST)
            
            # 处理Apipost集合
            if 'items' in apipost_data:  # 这是一个集合
                items = apipost_data.get('items', [])
                self._process_apipost_items(items, project, treenode)
            elif 'environments' in apipost_data:  # 这是一个环境变量文件
                # 处理环境变量逻辑可以在这里添加
                pass
            else:
                return Response({"message": "不支持的Apipost文件格式"}, status=status.HTTP_400_BAD_REQUEST)
            
            return Response(status=status.HTTP_201_CREATED)
        except Exception as e:
            return Response({"message": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    def _process_apipost_items(self, items, project, treenode, parent_name=""):
        """递归处理Apipost集合中的项目"""
        for item in items:
            if item.get('type') == 'folder':  # 这是一个文件夹
                folder_name = item.get('name', '')
                # 可以在这里创建子节点
                if 'children' in item:
                    self._process_apipost_items(item['children'], project, treenode, folder_name)
            elif item.get('type') == 'api':  # 这是一个API
                self._create_interface_from_apipost_request(item, project, treenode, parent_name)
    
    def _create_interface_from_apipost_request(self, api_item, project, treenode, parent_name=""):
        """从Apipost API创建接口"""
        name = api_item.get('name', '')
        if parent_name:
            name = f"{parent_name} - {name}"
        
        url = api_item.get('url', '')
        method = api_item.get('method', 'GET')
        
        # 处理请求头
        headers = {}
        for header in api_item.get('headers', []):
            headers[header.get('key', '')] = header.get('value', '')
        
        # 处理请求体
        body = {}
        if 'body' in api_item:
            body_data = api_item['body']
            if body_data.get('mode') == 'json' and 'json' in body_data:
                try:
                    body = json.loads(body_data['json'])
                except:
                    body = body_data['json']
            elif body_data.get('mode') == 'form-data':
                form_data = {}
                for item in body_data.get('formdata', []):
                    form_data[item.get('key', '')] = item.get('value', '')
                body = form_data
        
        # 构建接口数据
        interface_data = {
            "name": truncate_name("Apipost导入", name),
            "url": url,
            "method": method,
            "treenode": treenode,
            "project": project,
            "creator": self.request.user.username,
            "headers": headers,
            "request": {"json": body, "data": None, "params": {}}
        }
        
        # 创建接口
        serializer = newInterfaceSerializer(data=interface_data)
        if serializer.is_valid():
            serializer.save()
        else:
            print(f"导入失败: {serializer.errors}")


class SwaggerFileViewSet(APIView):
    """
    Swagger文件导入
    """
    parser_classes = (MultiPartParser, FormParser)
    
    def post(self, request, *args):
        try:
            # 获取请求数据
            file_obj = request.FILES.get('file')
            project = request.data.get('project')
            treenode = request.data.get('treenode')
            
            if not file_obj:
                return Response({"message": "未找到文件"}, status=status.HTTP_400_BAD_REQUEST)
            
            # 读取文件内容
            file_content = file_obj.read().decode('utf-8')
            
            # 根据文件扩展名判断格式
            file_name = file_obj.name.lower()
            if file_name.endswith('.json'):
                try:
                    swagger_data = json.loads(file_content)
                except json.JSONDecodeError:
                    return Response({"message": "无效的JSON文件"}, status=status.HTTP_400_BAD_REQUEST)
            elif file_name.endswith('.yaml') or file_name.endswith('.yml'):
                try:
                    swagger_data = yaml.safe_load(file_content)
                except yaml.YAMLError:
                    return Response({"message": "无效的YAML文件"}, status=status.HTTP_400_BAD_REQUEST)
            else:
                return Response({"message": "不支持的文件格式"}, status=status.HTTP_400_BAD_REQUEST)
            
            # 处理Swagger文档
            self._process_swagger_data(swagger_data, project, treenode)
            
            return Response(status=status.HTTP_201_CREATED)
        except Exception as e:
            return Response({"message": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    def _process_swagger_data(self, swagger_data, project, treenode):
        """处理Swagger文档数据"""
        # 判断Swagger版本
        if 'swagger' in swagger_data:
            version = swagger_data.get('swagger', '')
            if version.startswith('2'):
                self._process_swagger_v2(swagger_data, project, treenode)
            else:
                return Response({"message": f"不支持的Swagger版本: {version}"}, status=status.HTTP_400_BAD_REQUEST)
        elif 'openapi' in swagger_data:
            version = swagger_data.get('openapi', '')
            if version.startswith('3'):
                self._process_swagger_v3(swagger_data, project, treenode)
            else:
                return Response({"message": f"不支持的OpenAPI版本: {version}"}, status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response({"message": "无效的Swagger/OpenAPI文档"}, status=status.HTTP_400_BAD_REQUEST)
    
    def _process_swagger_v2(self, swagger_data, project, treenode):
        """处理Swagger 2.0文档"""
        base_path = swagger_data.get('basePath', '')
        paths = swagger_data.get('paths', {})
        
        for path, methods in paths.items():
            for method, operation in methods.items():
                if method in ['get', 'post', 'put', 'delete', 'patch']:
                    self._create_interface_from_swagger(
                        path, method, operation, base_path, project, treenode
                    )
    
    def _process_swagger_v3(self, swagger_data, project, treenode):
        """处理OpenAPI 3.0文档"""
        servers = swagger_data.get('servers', [])
        base_path = ''
        if servers and len(servers) > 0:
            base_path = servers[0].get('url', '')
        
        paths = swagger_data.get('paths', {})
        
        for path, methods in paths.items():
            for method, operation in methods.items():
                if method in ['get', 'post', 'put', 'delete', 'patch']:
                    self._create_interface_from_swagger(
                        path, method, operation, base_path, project, treenode
                    )
    
    def _create_interface_from_swagger(self, path, method, operation, base_path, project, treenode):
        """从Swagger路径创建接口"""
        name = operation.get('summary', '') or operation.get('operationId', '') or path
        
        # 构建URL
        url = f"{base_path}{path}"
        
        # 处理请求头
        headers = {}
        if 'consumes' in operation:
            headers['Content-Type'] = operation['consumes'][0]
        
        # 处理请求体
        body = {}
        if 'parameters' in operation:
            for param in operation['parameters']:
                if param.get('in') == 'body' and 'schema' in param:
                    # 这里可以进一步解析schema，但为简单起见，我们只记录schema的类型
                    body = {"type": param['schema'].get('type', 'object')}
        
        # 构建接口数据
        interface_data = {
            "name": truncate_name("Swagger导入", name),
            "url": url,
            "method": method.upper(),
            "treenode": treenode,
            "project": project,
            "creator": self.request.user.username,
            "headers": headers,
            "request": {"json": body, "data": None, "params": {}}
        }
        
        # 创建接口
        serializer = newInterfaceSerializer(data=interface_data)
        if serializer.is_valid():
            serializer.save()
        else:
            print(f"导入失败: {serializer.errors}")


class SwaggerUrlViewSet(APIView):
    """
    Swagger URL导入
    """
    parser_classes = (JSONParser,)
    
    def post(self, request, *args):
        try:
            # 获取请求数据
            url = request.data.get('url')
            project = request.data.get('project')
            treenode = request.data.get('treenode')
            
            if not url:
                return Response({"message": "未提供URL"}, status=status.HTTP_400_BAD_REQUEST)
            
            # 使用requests库获取Swagger文档
            import requests
            response = requests.get(url)
            if response.status_code != 200:
                return Response({"message": f"获取Swagger文档失败: {response.status_code}"}, status=status.HTTP_400_BAD_REQUEST)
            
            # 解析Swagger文档
            content_type = response.headers.get('Content-Type', '')
            if 'application/json' in content_type:
                swagger_data = response.json()
            elif 'application/yaml' in content_type or 'text/yaml' in content_type:
                swagger_data = yaml.safe_load(response.text)
            else:
                # 尝试作为JSON解析
                try:
                    swagger_data = response.json()
                except:
                    # 尝试作为YAML解析
                    try:
                        swagger_data = yaml.safe_load(response.text)
                    except:
                        return Response({"message": "不支持的文档格式"}, status=status.HTTP_400_BAD_REQUEST)
            
            # 创建SwaggerFileViewSet实例来处理解析后的数据
            swagger_handler = SwaggerFileViewSet()
            swagger_handler._process_swagger_data(swagger_data, project, treenode)
            
            return Response(status=status.HTTP_201_CREATED)
        except Exception as e:
            return Response({"message": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class JsFetchViewSet(APIView):
    """
    JS fetch代码导入
    """
    def post(self, request, *args):
        try:
            # 获取请求数据
            data = request.data
            method = data.get('method', 'GET')
            url = data.get('url', '')
            headers = data.get('headers', {})
            body = data.get('body', {})
            project = data.get('project', None)
            treenode = data.get('treenode', None)
            
            # 清理URL，移除多余的字符
            url = url.strip().strip('"').strip("'").replace('^', '').lstrip('"').rstrip('"')
            
            # 构建接口数据
            url_suffix = url.split('/')[-1] or url
            interface_data = {
                "name": truncate_name("JS导入", url_suffix),
                "url": url,
                "method": method,
                "treenode": treenode,
                "project": project,
                "creator": self.request.user.username,
                "headers": headers,
                "request": {"json": body, "data": None, "params": {}}
            }
            
            # 创建接口
            serializer = newInterfaceSerializer(data=interface_data)
            if serializer.is_valid():
                serializer.save()
                return Response(status=status.HTTP_201_CREATED)
            else:
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            return Response({"message": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class ProjectBoardView(APIView):
    def post(self, request, *args, **kwargs):
        project_id = request.data.get('project')
        starttime = request.data.get('starttime', None)
        endtime = request.data.get('endtime', None)

        # 构建用于缓存的键
        cache_key = f"project_data_{project_id}_{starttime}_{endtime}"

        # 尝试从缓存中获取数据
        cached_data = cache.get(cache_key)
        if cached_data:
            return Response(cached_data, status=status.HTTP_200_OK)

        try:
            project = Project.objects.get(id=project_id)
            if project:
                main = ProjectBoard(project)
                data = main.get_project_data_summary(starttime, endtime)
                # 将数据存入 Redis 缓存
                cache.set(cache_key, data, timeout=120)  # 设置缓存有效期为1小时
                return Response(data, status=status.HTTP_200_OK)
            else:
                return Response({"message": "项目不存在"}, status=status.HTTP_400_BAD_REQUEST)
        except Exception as e:
            return Response({"message": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
